package tushare

import (
	"tushare/model/mysql"
)

type Daily struct {
	Id        int64   `json:"id"`
	TsCode    string  `json:"ts_code"`
	TradeDate string  `json:"trade_date"`
	Open      float64 `json:"open"`
	High      float64 `json:"high"`
	Low       float64 `json:"low"`
	Close     float64 `json:"close"`
	PreClose  float64 `json:"pre_close"`
	Change    float64 `json:"change"`
	PctChg    float64 `json:"pct_chg"`
	Vol       float64 `json:"vol"`
	Amount    float64 `json:"amount"`
}

func DailyCreate(d Daily) {
	mysql.DB.Table("tushare_daily").Create(&d)
}

func DailyBatchCreate(sql string) {
	mysql.DB.Exec(sql)
}

func RecentLowAmont(tsCode, fromDate, toDate string) float64 {
	type amountStruct struct {
		Close float64 `json:"close"`
	}
	amount := amountStruct{}
	mysql.DB.Table("tushare_daily").Select("MIN(`close`) as `close`").Where("ts_code = ? and (trade_date BETWEEN ? AND ?)", tsCode, fromDate, toDate).Scan(&amount)

	return amount.Close
}

type RecentLowListStruct struct {
	TsCode    string  `json:"ts_code"`
	Name      string  `json:"name"`
	TradeDate string  `json:"trade_date"`
	Close     float64 `json:"close"`
	SecondLow float64 `json:"second_low"`
	Vol       float64 `json:"vol"`
	Amount    float64 `json:"amount"`
}

func RecentLowList(tradeDate string) []RecentLowListStruct {

	recentLowList := []RecentLowListStruct{}
	mysql.DB.Table("tushare_daily").Select(`
	tushare_daily.ts_code as ts_code,
	tushare_stock.name as name,
	tushare_daily.trade_date as trade_date,
	tushare_daily.close as close,
	tushare_reference_substance.second_low as second_low,
	tushare_daily.vol as vol,
	tushare_daily.amount as amount
	`).Joins(`
	left join tushare_reference_substance on tushare_daily.ts_code = tushare_reference_substance.ts_code
	`).Joins(`
	LEFT JOIN tushare_stock ON tushare_daily.ts_code = tushare_stock.ts_code
	`).Where(`tushare_daily.trade_date = ? AND tushare_daily.close - tushare_reference_substance.second_low <= 0
`, tradeDate).Order("tushare_daily.amount DESC").Scan(&recentLowList)

	return recentLowList
}

type fiveDayAvgStruct struct {
	Close float64 `json:"close"`
}

type dailyMinStruct struct {
	Min float64 `json:"min"`
}

func FiveDayAvg(tsCode string) float64 {
	fiveDayAvg := fiveDayAvgStruct{}

	mysql.DB.Raw(`
	SELECT SUM(a.close) as close FROM(SELECT
	close
FROM
	tushare_daily 
WHERE
	ts_code = ?
ORDER BY  trade_date DESC 
	LIMIT 5) a
	`, tsCode).Scan(&fiveDayAvg)
	return fiveDayAvg.Close
}

type backFiveDayAvgStruct struct {
	TsCode     string  `json:"ts_code"`
	Name       string  `json:"name"`
	TradeDate  string  `json:"trade_date"`
	Close      float64 `json:"close"`
	FiveDayAvg float64 `json:"five_day_avg"`
	Vol        float64 `json:"vol"`
	Amount     float64 `json:"amount"`
}

func BackFiveDayAvg(tradeDate string) []backFiveDayAvgStruct {
	backFiveDayAvgList := []backFiveDayAvgStruct{}
	// page := 1
	// pageSize := 100
	// offset := (page - 1) * pageSize

	mysql.DB.Table(`tushare_daily`).Select(` 
	tushare_daily.ts_code,
	tushare_stock.name,
	tushare_daily.trade_date,
	tushare_daily.close,
	tushare_reference_substance.five_day_avg,
	tushare_daily.vol,
	tushare_daily.amount
	`).Joins(`
	LEFT JOIN tushare_stock ON tushare_daily.ts_code = tushare_stock.ts_code
	`).Joins(`
	LEFT JOIN tushare_reference_substance ON tushare_daily.ts_code = tushare_reference_substance.ts_code
	`).Where(`
	tushare_daily.trade_date = ?
AND tushare_daily.close - tushare_reference_substance.five_day_avg >= 0.1
AND tushare_daily.close - tushare_reference_substance.five_day_avg <= 0.3
	`, tradeDate).Order(`
	tushare_daily.amount DESC
	`).Scan(&backFiveDayAvgList)
	return backFiveDayAvgList
}

/**
连续涨停天数
**/
func RaisingLimitDays(days int, tsCode string) []Daily {
	page := 1
	pageSize := days
	offset := (page - 1) * pageSize

	d := []Daily{}
	mysql.DB.Table("tushare_daily").Where("ts_code = ?", tsCode).Order("trade_date DESC").Limit(pageSize).Offset(offset).Scan(&d)
	return d
}

//获取均线价格
func AvgLine(tsCode, tradeDate string, limit string) float64 {
	fiveDayAvg := fiveDayAvgStruct{}

	mysql.DB.Raw(`
	SELECT SUM(a.close)/? as close FROM(SELECT
	close
FROM
	tushare_daily 
WHERE
	ts_code = ?
	AND trade_date <= ?
ORDER BY  trade_date DESC 
	LIMIT ?) a
	`, limit, tsCode, tradeDate, limit).Scan(&fiveDayAvg)
	return fiveDayAvg.Close
}

func CloseByTradeDate(tsCode, tradeDate string) float64 {
	fiveDayAvg := fiveDayAvgStruct{}

	mysql.DB.Raw(`
	SELECT
	close
FROM
	tushare_daily 
WHERE
	ts_code = ?
	AND trade_date = ?
	`, tsCode, tradeDate).Scan(&fiveDayAvg)
	return fiveDayAvg.Close
}

func AvgLineByDay(tsCode string, limit int64) float64 {
	fiveDayAvg := fiveDayAvgStruct{}

	mysql.DB.Raw(`
	SELECT SUM(a.close) as close FROM(SELECT
	close
FROM
	tushare_daily 
WHERE
	ts_code = ?
ORDER BY  trade_date DESC 
	LIMIT ?) a
	`, tsCode, limit).Scan(&fiveDayAvg)
	return fiveDayAvg.Close
}

func GetRowsByLimt(days int, tsCode, tradeDate string) []Daily {
	page := 1
	pageSize := days
	offset := (page - 1) * pageSize

	d := []Daily{}
	mysql.DB.Table("tushare_daily").Where("ts_code = ? and trade_date <= ?", tsCode, tradeDate).Order("trade_date DESC").Limit(pageSize).Offset(offset).Scan(&d)
	return d
}

func GetDaily(tsCode string) []Daily {
	d := []Daily{}
	mysql.DB.Table("tushare_daily").Raw(`
	SELECT * FROM
(
SELECT * FROM tushare_daily WHERE ts_code = ?
ORDER BY trade_date DESC
LIMIT ?
) a
ORDER BY trade_date ASC
	`, tsCode, 700).Scan(&d)
	return d
}

func DailyExist(tsCode, tradeDate string) Daily {
	d := Daily{}
	mysql.DB.Table("tushare_daily").Where("ts_code = ? AND trade_date = ?", tsCode, tradeDate).Scan(&d)
	return d
}

/**
获取一段时间内的最小值
**/
func GetDailyMinByLimit(tsCode string, limit int64) dailyMinStruct {
	dms := dailyMinStruct{}
	mysql.DB.Table("tushare_daily").Raw(`
	SELECT MIN(a.close) as min FROM
(
SELECT * FROM tushare_daily
WHERE ts_code = ?
ORDER BY trade_date DESC
LIMIT ?
) a
	`, tsCode, limit).Scan(&dms)
	return dms
}

func DailyRowsByLimt(days int, tsCode string) []Daily {
	page := 1
	pageSize := days
	offset := (page - 1) * pageSize

	d := []Daily{}
	mysql.DB.Table("tushare_daily").Where("ts_code = ?", tsCode).Order("trade_date DESC").Limit(pageSize).Offset(offset).Scan(&d)
	return d
}

func DailySumByLimit(tsCode string, limit, offset int64) float64 {
	fiveDayAvg := fiveDayAvgStruct{}

	mysql.DB.Raw(`
	SELECT SUM(a.close) as close FROM(SELECT
	close
FROM
	tushare_daily 
WHERE
	ts_code = ?
ORDER BY  trade_date DESC 
	LIMIT ? offset ?) a
	`, tsCode, limit, offset).Scan(&fiveDayAvg)
	return fiveDayAvg.Close
}
